#!/usr/bin/env bash
set -euo pipefail
# POS: media grab — Auto-download URL as audio or video (classify + route)
# POS_FLAGS: --audio --video --best --worst --output --no-playlist --cookies --dry-run
# POS_CONFIG: grab | grab.env | GRAB_DEFAULT=:Default mode for unknown domains (video or audio, default video)

source "$(dirname "$0")/../lib/common.sh" 2>/dev/null || source "$(dirname "$0")/common.sh"

# Load grab.env config (env-seam: GRAB_DEFAULT)
load_grab_config() {
    local f="$HOME/.config/linux_post_install/grab.env" k v
    [ -f "$f" ] || return 0
    while IFS='=' read -r k v; do
        [ -n "$k" ] || continue
        case "$k" in
            \#*) continue ;;
        esac
        v="${v%\"}"; v="${v#\"}"; v="${v%\'}"; v="${v#\'}"
        if [ -z "${!k:-}" ]; then
            export "$k"="$v"
        fi
    done < <(grep -E '^[A-Z_]+=' "$f" || true)
}

load_grab_config

# ── URL classification ─────────────────────────────────────────
classify_url() {
    local url="$1" mode="${GRAB_DEFAULT:-video}"
    case "$url" in
        *music.youtube.com*)  echo "audio" ;;
        *soundcloud.com*)     echo "audio" ;;
        *bandcamp.com*)       echo "audio" ;;
        *youtube.com*|*youtu.be*) echo "video" ;;
        *vimeo.com*)          echo "video" ;;
        *twitch.tv*)          echo "video" ;;
        *)                    echo "$mode" ;;
    esac
}

usage() {
    cat <<EOF
Usage: pos media grab [options] <url>

Auto-download a URL as audio or video. Classifies the domain and delegates
to 'pos media mp3' (audio) or 'pos media mp4' (video).

Options:
  --audio               Force audio (mp3) download
  --video               Force video (mp4) download
  --best                Best quality for video (default for non-interactive)
  --worst               Lowest quality for video
  -o, --output <dir>    Output directory (passed to mp3/mp4)
  --no-playlist         Download only the single video
  --cookies <file>      Netscape cookies.txt for age-gated content
  --dry-run             Print the command that would run, don't execute
  -h, --help            This help

Examples:
  pos media grab https://music.youtube.com/watch?v=abc
  pos media grab https://youtube.com/watch?v=xyz
  pos media grab --audio https://vimeo.com/123
  pos media grab --worst https://youtu.be/abc
  pos media grab --dry-run https://soundcloud.com/artist/track
EOF
    exit 0
}

# ── Arg parsing ────────────────────────────────────────────────
URL=""
FORCE_AUDIO=0
FORCE_VIDEO=0
BEST=0
WORST=0
DRY_RUN=0
EXTRA_ARGS=()

while [[ $# -gt 0 ]]; do
    case "$1" in
        -h|--help) usage ;;
        --audio) FORCE_AUDIO=1; shift ;;
        --video) FORCE_VIDEO=1; shift ;;
        --best)  BEST=1; shift ;;
        --worst) WORST=1; shift ;;
        -o|--output)
            [ $# -ge 2 ] || err "pos media grab: --output needs a value"
            EXTRA_ARGS+=(--output "$2"); shift 2 ;;
        --no-playlist) EXTRA_ARGS+=(--no-playlist); shift ;;
        --cookies)
            [ $# -ge 2 ] || err "pos media grab: --cookies needs a value"
            EXTRA_ARGS+=(--cookies "$2"); shift 2 ;;
        --dry-run) DRY_RUN=1; shift ;;
        -*) err "pos media grab: Unknown option: $1 (see --help)" ;;
        *)
            [ -z "$URL" ] && URL="$1" && shift || err "pos media grab: Unexpected argument: $1" ;;
    esac
done

[ -n "$URL" ] || usage

# Validate URL scheme
case "$URL" in
    http://*|https://*) ;;
    *) err "pos media grab: not a valid URL: $URL (must start with http:// or https://)" ;;
esac

# Validate mutually exclusive overrides
[ "$FORCE_AUDIO" -eq 1 ] && [ "$FORCE_VIDEO" -eq 1 ] && \
    err "pos media grab: --audio and --video are mutually exclusive"
[ "$BEST" -eq 1 ] && [ "$WORST" -eq 1 ] && \
    err "pos media grab: --best and --worst are mutually exclusive"

# ── Classification ─────────────────────────────────────────────
mode=""
if [ "$FORCE_AUDIO" -eq 1 ]; then
    mode="audio"
elif [ "$FORCE_VIDEO" -eq 1 ]; then
    mode="video"
else
    mode="$(classify_url "$URL")"
fi

# ── Build delegated command ────────────────────────────────────
DELEGATE_ARGS=()

if [ "$mode" = "audio" ]; then
    DELEGATE_ARGS=(pos media mp3 "${EXTRA_ARGS[@]}")
else
    # mp4 route: --best by default (non-interactive), --worst if user passes it
    if [ "$WORST" -eq 1 ]; then
        DELEGATE_ARGS=(pos media mp4 --worst "${EXTRA_ARGS[@]}")
    else
        DELEGATE_ARGS=(pos media mp4 --best "${EXTRA_ARGS[@]}")
    fi
fi

# ── Dry run ────────────────────────────────────────────────────
if [ "$DRY_RUN" -eq 1 ]; then
    echo "${DELEGATE_ARGS[*]} $URL"
    exit 0
fi

# ── Execute ────────────────────────────────────────────────────
output=""
rc=0
if output=$("${DELEGATE_ARGS[@]}" "$URL" 2>&1); then
    rc=0
else
    rc=$?
fi

if [ "$rc" -ne 0 ]; then
    # Summarize stderr for the user
    summary="$(printf '%s' "$output" | grep -i 'error\|fail' | head -1 || true)"
    [ -z "$summary" ] && summary="exit code $rc"
    err "pos media grab: ❌ Download failed: $summary"
fi

# ── Metadata + summary ────────────────────────────────────────
title=""
duration=""
file_path=""

# Determine expected output directory
if [ "$mode" = "audio" ]; then
    out_dir="$HOME/Music"
    for (( i=0; i<${#EXTRA_ARGS[@]}; i++ )); do
        if [ "${EXTRA_ARGS[$i]}" = "--output" ] && [ $(( i + 1 )) -lt ${#EXTRA_ARGS[@]} ]; then
            out_dir="${EXTRA_ARGS[$(( i + 1 ))]}"
            break
        fi
    done
    file_ext="mp3"
else
    out_dir="$HOME/Videos"
    for (( i=0; i<${#EXTRA_ARGS[@]}; i++ )); do
        if [ "${EXTRA_ARGS[$i]}" = "--output" ] && [ $(( i + 1 )) -lt ${#EXTRA_ARGS[@]} ]; then
            out_dir="${EXTRA_ARGS[$(( i + 1 ))]}"
            break
        fi
    done
    file_ext="mp4"
fi

# Fetch metadata (fast, no download)
if command -v yt-dlp &>/dev/null; then
    meta="$(yt-dlp --print title --print duration_string --no-warnings "$URL" 2>/dev/null || true)"
    title="$(printf '%s' "$meta" | sed -n '1p')"
    duration="$(printf '%s' "$meta" | sed -n '2p')"
fi

# Find the downloaded file (most recent matching extension in out_dir)
if [ -d "$out_dir" ]; then
    file_path="$(find "$out_dir" -maxdepth 1 -name "*.$file_ext" -printf '%T@ %p\n' 2>/dev/null \
        | sort -rn | head -1 | cut -d' ' -f2- || true)"
fi

# Build summary
[ -z "$title" ] && title="$(basename "$URL" | sed 's/[?#].*//')"
[ -z "$duration" ] && duration="?"

if [ "$mode" = "audio" ]; then
    emoji="🎵"
else
    emoji="🎬"
fi

echo "$emoji Downloaded: $title ($duration)"

if [ -n "$file_path" ] && [ -f "$file_path" ]; then
    file_size="$(stat --printf='%s' "$file_path" 2>/dev/null || echo "0")"
    # Format size in human-readable form
    if [ "$file_size" -ge 1073741824 ]; then
        size_human="$(awk "BEGIN { printf \"%.1f GB\", $file_size / 1073741824 }")"
    elif [ "$file_size" -ge 1048576 ]; then
        size_human="$(awk "BEGIN { printf \"%.1f MB\", $file_size / 1048576 }")"
    elif [ "$file_size" -ge 1024 ]; then
        size_human="$(awk "BEGIN { printf \"%.1f KB\", $file_size / 1024 }")"
    else
        size_human="${file_size} B"
    fi
    # Show path relative to HOME
    rel_path="${file_path/#$HOME/\~}"
    echo "📁 $rel_path ($size_human)"
else
    echo "📁 $out_dir/ ($file_ext)"
fi
